#!/usr/bin/python
# coding=utf-8
# author=He


import pika
import sys
import config
import json
from datetime import datetime


class RabbitMqService:

    channel = ''
    connection = ''

    def __init__(self, queue_name, exchange):
        """
        :param queue_name: The queue name
        :param exchange: The exchange name consists of a non-empty
        :type queue_name str
        :type exchange str
        """
        try:
            self.__queue_name = queue_name
            self.__exchange = exchange
            credentials = pika.PlainCredentials(username=config.mq_user, password=config.mq_password)
            self.__connection = pika.BlockingConnection(pika.ConnectionParameters(
                config.mq_host, config.mq_port, config.mq_hosts, credentials))
            self.__channel = self.__connection.channel()
            if self.__connection.is_open is False:
                print 'RabbitMq Open Connection Fail'
                sys.exit(1)
            if self.__channel.is_open is False:
                print 'RabbitMq Open Channel Fail'
                sys.exit(1)
        except Exception as e:
            print e

    def send(self, data, queue_durable=True, exchange_type='fanout'):
        """
        :param data: The message body
        :param queue_durable: Survive a reboot of RabbitMQ
        :param exchange_type: The exchange type to use
        :return: Void
        """

        self.__channel.queue_declare(queue=self.__queue_name, passive=False, durable=True, exclusive=False)
        self.__channel.exchange_declare(exchange=self.__exchange, exchange_type=exchange_type, durable=queue_durable)
        self.__channel.queue_bind(queue=self.__queue_name, exchange=self.__exchange)
        if 'date' in data:
            self.__add_queue(data=data)

    def __add_queue(self, data,):
        """
        :param data: The message body
        :return: Void
        """
        self.__channel.basic_publish(routing_key=self.__queue_name, body=json.dumps(data),
                                     properties=pika.BasicProperties(delivery_mode=2), exchange=self.__exchange)

    def get__queue_name(self):
        """
        :type: string
        :return: self.__queue_name 
        """
        return self.__queue_name

    def get__exchange(self):
        """
        :type: string
        :return: self.__exchange 
        """
        return self.__exchange

    def get__channel(self):
        """
        :rtype: pika.synchronous_connection.BlockingChannel
        :return: self.__channel 
        """
        return self.__channel

    def get__connection(self):
        return self.__connection

    def close(self):
        """
        :return: Void
        """
        is_closed = self.is_closed()
        if is_closed is False:
            self.__connection.close()

    def is_closed(self):
        """
        :return: bool
        """
        return self.__connection.is_closed

    def is_open(self):
        """
        :return:bool 
        """
        return self.__connection.is_open

    def get_connection_status(self):
        """
        :return:bool 
        """
        self.__connection.is_open()


class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.__str__()
        return json.JSONEncoder.default(self, obj)
